<!DOCTYPE html>
<html>
<head>
    <style type="text/css">
        #theCanvas {
            border: 1px solid #000;
        }

    </style>
    <script src="http://code.jquery.com/jquery-1.7.1.js"></script>
    <script src="kinetic-v3.6.2.min.js"></script>
    <script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
</head>
<body>
<script type="TEXT/JAVASCRIPT">

    var factory = createRect;

    var shapes = [];
    var redoArray = [];

    var currColor = "Black";
    var lineWidth = "3";

    var currFont = "Calibri";
    var currFontSize = "40pt";
    var textContent = "";


    var selection = [];

    var canv_height;
    var canv_width;

    var mouseX = 999;
    var mouseY = 999;

    var drawingActive = false;
    var dragging = false;
    var draggingMode = false;

    function Rectangle(x, y) {
        this.ClassName = "Rectangle";
        this.x = x;
        this.y = y;
        this.endX = x;
        this.endY = y;
        this.color = currColor;
        this.lineWidth = lineWidth;
    }
    Rectangle.prototype.Draw = function (ctx) {
        //check stroke or fill
        var minX = Math.min(this.x, this.endX);
        var minY = Math.min(this.y, this.endY);
        var width = Math.abs(this.endX - this.x);
        var height = Math.abs(this.endY - this.y);

        ctx.lineWidth = this.lineWidth;
        ctx.strokeStyle = this.color;
        ctx.strokeRect(minX, minY, width, height);
    };
    Rectangle.prototype.SetEnd = function (x, y) {
        this.endX = x;
        this.endY = y;
    };
    Rectangle.prototype.contains = function (x, y) {
        var minX = Math.min(this.x, this.endX);
        var minY = Math.min(this.y, this.endY);
        var width = Math.abs(this.endX - this.x);
        var height = Math.abs(this.endY - this.y);
        if ((minX <= x && x <= (minX + width))
                && (minY <= y && y <= (minY + height))){
            console.log("Rectangle contains returns true");
            return true;
        }
        console.log("Rectangle contains returns false");
        return false;
    };
    Rectangle.prototype.MoveStart = function(x,y){
        this.lastMoveX = x;
        this.lastMoveY = y;
    };
    Rectangle.prototype.MoveTo = function(x,y){
        var diffX = x - this.lastMoveX;
        var diffY = y - this.lastMoveY;

        this.x += diffX;
        this.y += diffY;
        this.endX += diffX;
        this.endY += diffY;

        this.lastMoveX = x;
        this.lastMoveY = y;
    };

    // Circle
    function Circle(x, y) {
        this.ClassName = "Circle";
        this.x = x;
        this.y = y;
        this.endX = x;
        this.endY = y;
        this.color = currColor;
        this.lineWidth = lineWidth;
    }
    Circle.prototype.Draw = function (ctx) {
        var minX = Math.min(this.x, this.endX);
        var minY = Math.min(this.y, this.endY);
        var width = Math.abs(this.endX - this.x);
        var height = Math.abs(this.endY - this.y);

        ctx.strokeStyle = this.color;
        ctx.lineWidth = this.lineWidth;
        ctx.beginPath();
        ctx.arc(minX + (width / 2), minY + (height / 2), width / 2, 0, 2 * Math.PI, false);
        ctx.stroke();
    };
    Circle.prototype.SetEnd = function (x, y) {
        this.endX = x;
        this.endY = y;
    };
    Circle.prototype.contains = function (mx, my) {
        var minX = Math.min(this.x, this.endX);
        var minY = Math.min(this.y, this.endY);
        var width = Math.abs(this.endX - this.x);
        var height = Math.abs(this.endY - this.y);

        if((minX <= mx && mx <= (minX + width))
                && (minY <= my && my <= (minY + height))){
            return true;
        }
        return false;
    };
    Circle.prototype.MoveStart = function(x,y){
        this.lastMoveX = x;
        this.lastMoveY = y;
    };
    Circle.prototype.MoveTo = function(x,y){
        var diffX = x - this.lastMoveX;
        var diffY = y - this.lastMoveY;

        this.x += diffX;
        this.y += diffY;
        this.endX += diffX;
        this.endY += diffY;

        this.lastMoveX = x;
        this.lastMoveY = y;
    };

    //Line
    function Line(x,y){
        this.ClassName = "Line";
        this.x = x;
        this.y = y;
        this.endX = x;
        this.endY = y;
        this.color = currColor;
        this.lineWidth = lineWidth;
    }
    Line.prototype.Draw = function(ctx){
        ctx.strokeStyle = this.color;
        ctx.lineWidth = this.lineWidth;
        ctx.beginPath();
        ctx.moveTo(this.x,this.y);
        ctx.lineTo(this.endX,this.endY);
        ctx.stroke();
    };
    Line.prototype.SetEnd = function (x, y) {
        this.endX = x;
        this.endY = y;
    };
    Line.prototype.contains = function (mx, my) {
        var minX = Math.min(this.x, this.endX);
        var minY = Math.min(this.y, this.endY);
        var width = Math.abs(this.endX, this.x);
        var height = Math.abs(this.endY, this.y);

        if((minX <= mx && mx <= (minX + width))
                && (minY <= my && my <= (minY + height))){
            return true;
        }
        return false;
    };
    Line.prototype.MoveStart = function(x,y){
        this.lastMoveX = x;
        this.lastMoveY = y;
    };
    Line.prototype.MoveTo = function(x,y){
        var diffX = x - this.lastMoveX;
        var diffY = y - this.lastMoveY;

        this.x += diffX;
        this.y += diffY;
        this.endX += diffX;
        this.endY += diffY;

        this.lastMoveX = x;
        this.lastMoveY = y;
    };

    // Pen
    function Pen(x, y) {
        this.ClassName = "Pen";
        this.points = [];
        this.mouse = false;
        this.color = currColor;
        this.lineWidth = lineWidth;

        var firstPoint =
        {
            "x":x,
            "y":y
        };

        this.points.push(firstPoint);
    }
    Pen.prototype.SetEnd = function (x, y) {
        var nextPoint =
        {
            "x":x,
            "y":y
        };
        this.points.push(nextPoint);
    }
    Pen.prototype.Draw = function (ctx) {
        ctx.beginPath();
        ctx.lineWidth = this.lineWidth;
        ctx.strokeStyle = this.color;
        for (i = 0; i < this.points.length; i++) {
            ctx.lineTo(this.points[i].x, this.points[i].y);

            ctx.stroke();
        }
    };
    //This does not work
    Pen.prototype.contains = function (mx, my) {
        var minX = Math.min(this.x, this.endX);
        var minY = Math.min(this.y, this.endY);
        var width = Math.abs(this.endX -this.x);
        var height = Math.abs(this.endY - this.y);

        if((minX <= mx && mx <= (minX + width))
                && (minY <= my && my <= (minY + height))){
            console.log("Pen contains returns true");
            return true;
        }
        console.log("Pen contains returns false");
        return false;
        /*
        console.log( "Pen contains returns : " + this.mouse);
        return this.mouse;
        //console.log( this.points);

        var checkpoint =
        {
            "x":mx,
            "y":my
        };
        console.log(" inArray check : " + $.inArray(checkpoint, this.points) )
        return ( $.inArray(mx, shapes) );
*/
        /*
        for (i = 0; i < this.points.length; i++){
            console.log( "point x : " + this.points[i].x);
            console.log( "point y : " + this.points[i].y);
            console.log( "mx : " + mx);
            console.log( "my : " + my);

            if (this.points[i].x == mx || this.points[i].y == my){
                console.log("pen contains is true");
                return true;
            }
            else{
                console.log("pen contains is false");
                return false;
            }
        }
        /*
        return  (this.x <= mx) && (this.x + this.endX >= mx) &&
                (this.y <= my) && (this.y + this.endY >= my);
                */
    };
    Pen.prototype.MoveStart = function(x,y){
        this.lastMoveX = x;
        this.lastMoveY = y;
    };
    Pen.prototype.MoveTo = function(x,y){
        var diffX = x - this.lastMoveX;
        var diffY = y - this.lastMoveY;

        this.x += diffX;
        this.y += diffY;
        this.endX += diffX;
        this.endY += diffY;

        this.lastMoveX = x;
        this.lastMoveY = y;
    };

    //Text
    function Text(x,y){
        this.ClassName = "Text";
        this.x = x;
        this.y = y;
        this.endX = x;
        this.endY = y;
        this.color = currColor;
        this.font = currFontSize + " " + currFont;
        this.textContent = textContent;
    }
    Text.prototype.SetEnd = function(x,y){
        this.endX = x;
        this.endY = y;
    };
    Text.prototype.Draw = function(ctx){
        ctx.font = this.font;
        ctx.fillStyle = this.color;
        ctx.fillText(this.textContent, this.x, this.y);
    };
    Text.prototype.contains = function (mx, my) {
        return  (this.x - 40 <= mx) && (this.x + this.endX - 40 >= mx) &&
                (this.y - 40 <= my) && (this.y - 40 + this.endY >= my);

    };
    Text.prototype.MoveStart = function(x,y){
        this.lastMoveX = x;
        this.lastMoveY = y;
    };
    Text.prototype.MoveTo = function(x,y){
        var diffX = x - this.lastMoveX;
        var diffY = y - this.lastMoveY;

        this.x += diffX;
        this.y += diffY;
        this.endX += diffX;
        this.endY += diffY;

        this.lastMoveX = x;
        this.lastMoveY = y;
    };

    function createRect(x, y) {
        return new Rectangle(x, y);
    }

    function Redraw(ctx) {
        ctx.clearRect(0, 0, 800, 400);
        for (var i = 0; i < shapes.length; i++) {
            shapes[i].Draw(ctx);
        }
    }

    function setShape(shapeName) {
        factory = function (x, y) {
            return eval("new " + shapeName + "(x,y)");
        }
    }

    function Stringify(arr) {
        return JSON.stringify(arr);
    }

    function Arrayfy(str) {

    }

    $(document).ready(function () {

        $("#text_input").text(textContent);

        var canvas = document.getElementById("theCanvas");
        var context = canvas.getContext("2d");
        canv_height = canvas.height;
        canv_width = canvas.width;
        $("#theCanvas").mousedown(function (e) {
            var mouseX = e.pageX - this.offsetLeft;
            var mouseY = e.pageY - this.offsetTop;
            if(draggingMode){
                selection = [];
                drawingActive = false;
                var l = shapes.length;
                for (var i = l - 1; i >= 0; i--) {
                    if (shapes[i].contains(mouseX, mouseY)) {
                        var mySel = shapes[i];
                        mySel.MoveStart(mouseX, mouseY);
                        dragging = true;
                        selection.push(mySel);
                        return;
                    }
                }
            }else{
                drawingActive = true;
                shapes.push(factory(mouseX, mouseY));
            }
        });

        $("#theCanvas").mousemove(function (e) {
            var x = e.pageX - this.offsetLeft;
            var y = e.pageY - this.offsetTop;

            if (drawingActive) {
                var lastShape = shapes[ shapes.length - 1 ];
                lastShape.SetEnd(x, y);

                if (lastShape != undefined) {
                    lastShape.SetEnd(x, y);
                    Redraw(context);
                }
            }
            if(dragging){
                selection[0].MoveTo(x, y);
                Redraw(context);
            }
        });

        $("#theCanvas").mouseup(function (e) {
            drawingActive = false;
            dragging = false;
        });

        $('#theCanvas').mouseleave(function (e) {
            dragging = false;
            drawingActive = false;
        });

        $("#saveTemplate").click(function () {
            var title = prompt("Whats the name of the template?");
            if (title != "") {
                var stringifiedArray = Stringify(shapes);
                var param = { "user" : "dabs",
                    "name" : title,
                    "content" : stringifiedArray,
                    "template" : true
                };

            $.ajax({
                type: "POST",
                contentType: "application/json; charset=utf-8",
                url: "http://whiteboard.apphb.com/Home/Save",
                data: param,
                dataType: "jsonp",
                crossDomain: true,
                success: function (data) {
                    var arr = [{ "ID": data.ID,
                        "WhiteboardTitle": title
                    }];
                    $("#templateTemplate").tmpl(arr).appendTo("#templateSelect");
                },
                error: function (xhr, err) {
                    alert("error");
                }
            });
            }
        });

        $("#templateSelect").dblclick(function (e) {
            var item = this.options[this.selectedIndex].value;
            var param = { "id": item };
            $.ajax({
                type: "GET",
                contentType: "application/json; charset=utf-8",
                url: "http://whiteboard.apphb.com/Home/Getwhiteboard",
                data: param,
                dataType: "jsonp",
                crossDomain: true,
                success: function (data) {
                    var items = JSON.parse(data.WhiteboardContents);
                    for (var i = 0; i < items.length; i++){
                        var func = eval(items[i].ClassName);
                        items[i].__proto__ = func.prototype;
                        shapes.push(items[i]);
                    }

                    Redraw(context);
                },
                error: function (xhr, err) {
                    alert("error:\n" + xhr + "\n" + err);
                }
            });
        });

        var param = {
            "user": "dabs",
            "template": true
        };

        $.ajax({
            type: "GET",
            contentType: "application/json; charset=utf-8",
            url: "http://whiteboard.apphb.com/Home/GetList",
            data: param,
            dataType: "jsonp",
            crossDomain: true,
            success: function (data) {
                $("#templateTemplate").tmpl(data).appendTo("#templateSelect");
            },
            error: function (xhr, err) {
                alert("error:\n" + xhr + "\n" + err);
            }
        });

        $('#drag_btn').click(function() {
            if (draggingMode == true){
                $('#drag_btn').html('Disable dragging');
            } else {
                $('#drag_btn').html('Enable dragging');
            }
        });

        $('#color').change(function() {
            currColor = $(this).find("option:selected").text();
        });
        $('#line_width').change(function() {
            lineWidth = $(this).find("option:selected").text();
        });
        $('#font_type').change(function() {
            currFont = $(this).find("option:selected").text();
        });
        $('#font_size').change(function() {
            currFontSize = $(this).find("option:selected").text();
        });
        $("#text_input").keyup(function () {
            textContent = $(this).val();
        }).keyup();

        $('#undo_btn').click(function() {
            if (shapes.length > 0) {
                redoArray.push(shapes.pop());
                Redraw(context);
            }
        });
        $('#redo_btn').click(function() {
            if (redoArray.length > 0) {
                shapes.push(redoArray.pop());
                Redraw(context);
            }
        });
    });

</script>
<canvas id="theCanvas" width="800" height="400">
    <p>No support for canvas, sorry</p>
</canvas>
<p>
<button onclick="setShape('Rectangle');">Rectangle</button>
<button onclick="setShape('Circle');">Circle</button>
<button onclick="setShape('Pen');">Pen</button>
<button onclick="setShape('Line');">Line</button>
<button onclick="setShape('Text');">Text</button>
<input id="text_input" type="text">
<button id="saveTemplate">Save template</button>
<button id="drag_btn" onclick="if (draggingMode) draggingMode = false; else draggingMode=true">Enable dragging</button>
<button id="undo_btn">Undo</button>
<button id="redo_btn">Redo</button>
</p>
<label>Color</label>
<select id="color">
    <option>Black</option>
    <option>Red</option>
    <option>Green</option>
    <option>Blue</option>
</select>
<label>Line width</label>
<select id="line_width">
    <option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
</select>
<label>Font</label>
<select id="font_type">
    <option>Calibri</option>
    <option>Times New Roman</option>
</select>
<label>Font size</label>
<select id="font_size">
    <option>20pt</option>
    <option>30pt</option>
</select>
<p>
    <label>Templates</label>
</p>
<p>
    <select multiple="multiple" id="templateSelect">

    </select>
    <script id="templateTemplate" type="text/html">
        <option value='${ID}'>${WhiteboardTitle}</option>
    </script>
</p>
</body>
</html>